package com.gopay.checkorder.service.task;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.dao.BisBankOrderQueryDAO;
import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.checkorder.service.task.thread.UnAcctCompensateThread;
import com.gopay.common.constants.bank.BankOrderType;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.StringTools;

/**
 
 * @author lizheng
 *
 */
public class UnAcctCompensateTaskImpl implements Task {
    
	private final static Logger logger = LoggerFactory.getLogger(UnAcctCompensateTaskImpl.class);

	@Resource(name = "commonQueryDAO")
    private CommonQueryDAO commonQueryDAO;
    
    @Resource(name = "bisBankOrderQueryDAO")
    private BisBankOrderQueryDAO bisBankOrderQueryDAO;
    
    @Resource(name = "bankOrderManager")
    protected BankOrderManager bankOrderManager;

    private ExecutorService threadPool = Executors.newFixedThreadPool(10);
    
    private int MAX_SIZE=100;
    
    /**
     * 任务执行
     */
    public void doTask() {
        try{
            StopWatch sw=new StopWatch();
            sw.start();
            logger.error("未入账补偿任务------start");
            
	        List<BankOrder> list = getSendBankOrderList();
	        logger.error("未入账补偿记录总数="+list.size());

	        //订单队列	            
            ConcurrentLinkedQueue<BankOrder> queue=new ConcurrentLinkedQueue<BankOrder>();
            queue.addAll(list);

            //同步锁存器
            CountDownLatch latch = new CountDownLatch(queue.size());
            
            //对单
            for(BankOrder bankOrder:list){
            	logger.error("未入账补偿------BankOrder:"+bankOrder.toString());
            	UnAcctCompensateThread thread=new UnAcctCompensateThread(bankOrderManager,queue,latch);
                threadPool.execute(thread);
                
            }
            
            // 同步锁存器等待所有线程执行完成
            if(!latch.await(118, TimeUnit.SECONDS)){
                logger.error("未入账补偿任务,同步锁存器等待超时了 latch.count=" + latch.getCount());
                threadPool.awaitTermination(1, TimeUnit.SECONDS);
            }

     		  
            logger.error("未入账补偿任务------end");
            sw.stop();
	        
            
        }catch (Throwable t) {
        	logger.error("未入账补偿任务,执行对单Task时出现异常" ,t);
		}       
    }
    public List<BankOrder> getSendBankOrderList() {
		List<Object[]> list = getUnAcctOrder( 1, MAX_SIZE);
		List<BankOrder> orders = new ArrayList<BankOrder>();
		for (Object[] bankOrderId : list) {
			BankOrder bankOrder = bisBankOrderQueryDAO.find(BankOrder.class, StringTools.checkNulltoString(bankOrderId[0]));
			orders.add(bankOrder);
		}
		return orders;
	}
	public List<Object[]> getUnAcctOrder(int pageIndex, int pageSize){
    	StringBuffer sql = new StringBuffer(250);
    	sql.append("select b.GOPAY_OUT_ORDER_ID,b.GOPAY_ORDER_ID from BIS_BANK_MAIN_ORDER b ");
		sql.append(" left join cps_gen_main_order c on b.gopay_order_id = c.gopay_order_id ");
		sql.append(" where b.order_status in ('03', '02', '04') ");
    	sql.append(" and c.txn_sta_cd in (30101, 30102, 20002) ");
    	sql.append(" and c.gopay_int_txn_cd = :txnCd ");
    	sql.append(" and b.ORDER_TYPE = :orderType ");
    	
    	sql.append(" and b.SEND_BANK_TM >to_date(:beginTime ,'yyyyMMddHH24miss') ");
    	sql.append(" and b.tran_finish_time <to_date(:bearTime ,'yyyyMMddHH24miss') ");
    	
    	Map<String, Object> params = new HashMap<String, Object>();
//    	params.put("orderStatus", orderStatus);
    	params.put("orderType", BankOrderType.GOPAY_BIS_ORDER);
    	params.put("txnCd", IntTxnCd._00100.value);
    	params.put("beginTime", recentlyTime());
    	params.put("bearTime", bearTime());
    	List<Object[]> list = commonQueryDAO.findBySql(sql.toString(), params, pageIndex, pageSize);
    	return list;
    }
	private String recentlyTime(){
		Calendar calendar = Calendar.getInstance();
		
		//开始时间--最近1天
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		String beginTime=DateUtils.format(calendar.getTime(), "yyyyMMddHHmmss");
		
		return beginTime;
	}
	private String bearTime(){
		Calendar calendar = Calendar.getInstance();
		
		//开始时间--最近1小时
		calendar.setTime(new Date());
		calendar.add(Calendar.HOUR, -1);
		String beginTime=DateUtils.format(calendar.getTime(), "yyyyMMddHHmmss");
		
		return beginTime;
	}
}